package org.zz.mxhidfingerdriver;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;

import com.fingerUsb.Callback;
import com.fingerUsb.FingerResult;
import com.fingerUsb.USBComm;
import com.siecom.module.DeviceInterface;

import org.zz.jni.zzFingerAlg;
import org.zz.mxhidfingerdriver.MXHidFingerComm;
import org.zz.protocol.MXCommand;
import org.zz.protocol.MXLog;
import org.zz.protocol.MXVersion;
import org.zz.tool.BMP;
import org.zz.tool.ImgFormatTrans;
import org.zz.tool.mxJavaBase64;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MXFingerDriver {
    private MXHidFingerComm m_hidFingerComm;
    private Handler m_fHandler = null;
    private zzFingerAlg alg;
    private static ExecutorService threadPool = Executors.newFixedThreadPool(1);

    public MXFingerDriver(USBComm m_usbBase) {
        this.m_fHandler = null;

        this.alg = new zzFingerAlg();
        this.m_hidFingerComm = new MXHidFingerComm(m_usbBase);
    }


    public void getFeature(int timeOut, Callback callback) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                byte[] bTzBuf = new byte[344];
                byte[] bImgBuf = new byte[30400];
                short iImgLen = 30400;
                int nRet = mxGetImage(bImgBuf, iImgLen, timeOut, 0);
                if (nRet == 0) {
                    nRet = alg.mxGetTz172(bImgBuf, bTzBuf);
                    int nRet1;
                    if (nRet != 1) {
                        nRet1 = -6;
                        if (callback != null) {
                            callback.onError(nRet1);
                        }
                    } else {
                        FingerResult result = new FingerResult();
//                        String strSDCard = DeviceInterface.getSDCardPath();
//                        String fingerImgPath = null;
//                        if(strSDCard!=null)
//                        {
//                            fingerImgPath = strSDCard+"/finger.bmp";
//                        }
//                        BMP.SaveBMP(fingerImgPath, bImgBuf, 152, 200);
//                        Bitmap bitmap = BitmapFactory.decodeFile(fingerImgPath);
//                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
                        Bitmap bitmap = BMP.Raw2Bimap(bImgBuf,152,200);
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
                        result.setImgBytes(baos.toByteArray());
                        try {
                            baos.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        result.setStatus(0);
                        result.setResult(new String(bTzBuf));
                        callback.onSuccess(result);
                    }

                } else {
                    if (callback != null) {
                        callback.onError(nRet);
                    }
                }
            }
        };
        threadPool.submit(runnable);
    }

    public String[] SCCBA_ReadFinger(String fingerImgPath, String fingerType, String strTimeout) {
        byte[] bTzBuf = new byte[344];
        byte[] bImgBuf = new byte[30400];
        short iImgLen = 30400;
        int iTimeOut = Integer.parseInt(strTimeout) * 1000;
        int nRet = this.mxGetImage(bImgBuf, iImgLen, iTimeOut, 0);
        String[] iBMPFileSize1;
        if (nRet != 0) {
            iBMPFileSize1 = new String[]{Integer.toString(nRet), null};
            switch (nRet) {
                case -101:
                    iBMPFileSize1[1] = "无权限访问设备";
                    break;
                case -100:
                    iBMPFileSize1[1] = "设备未连接";
                    break;
                case -5:
                    iBMPFileSize1[1] = "上传图像失败";
                    break;
                case -4:
                    iBMPFileSize1[1] = "采集图像失败";
                    break;
                case -3:
                    iBMPFileSize1[1] = "等待手指超时";
                    break;
                case -2:
                    iBMPFileSize1[1] = "用户取消操作";
                    break;
                case -1:
                    iBMPFileSize1[1] = "打开设备失败";
                    break;
                default:
                    iBMPFileSize1[1] = "其他异常";
            }

            return iBMPFileSize1;
        } else {
            nRet = this.alg.mxGetTz172(bImgBuf, bTzBuf);
            byte nRet1;
            if (nRet != 1) {
                nRet1 = -6;
                iBMPFileSize1 = new String[]{Integer.toString(nRet1), "提取特征失败"};
                return iBMPFileSize1;
            } else {
                short iBMPFileSize = 0;
                if (fingerImgPath != null) {
                    nRet = BMP.SaveBMP(fingerImgPath, bImgBuf, 152, 200);
                    if (nRet != 0) {
                        nRet1 = -7;
                        String[] iTzSize1 = new String[]{Integer.toString(nRet1), "保存指纹图片失败"};
                        return iTzSize1;
                    }

                    iBMPFileSize = 31478;
                }

                short iTzSize = 172;
                String[] aryRet = new String[]{Integer.toString(nRet), fingerImgPath, Integer.toString(iBMPFileSize), new String(bTzBuf), Integer.toString(iTzSize)};
                return aryRet;
            }
        }
    }

    public String mxGetAlgVersion() {
        byte[] version = new byte[100];
        this.alg.mxGetVersion(version);
        return new String(version);
    }

    public String mxGetDriverVersion() {
        return MXVersion.strVersion;
    }

    public int mxSetPVID(int iPid, int iVid) {
        MXCommand.VENDORID = iVid;
        MXCommand.PRODUCTID = iPid;
        return 0;
    }

    public int mxSetLog(boolean bLog) {
        MXLog.LOG_MSG = bLog;
        return 0;
    }

    public String getDevAttribute() {
        return this.m_hidFingerComm.getDevAttribute();
    }

    public int mxGetDevVersion(byte[] bVersion) {
        return this.m_hidFingerComm.mxGetDevVersion(bVersion);
    }

    public int mxGetImage(byte[] bImgBuf, int iImgLen, int iTimeOut, int iFlagLeave) {
        return this.m_hidFingerComm.mxGetImage(bImgBuf, iImgLen, iTimeOut, iFlagLeave);
    }

    public int mxGetImageB64(byte[] bImgBufB64, int iImgB64Len, int iTimeOut, int iFlagLeave) {
        boolean nRet = false;
        short iImgLen = 30400;
        byte[] bImgBuf = new byte[30400];
        int nRet1 = this.m_hidFingerComm.mxGetImage(bImgBuf, iImgLen, iTimeOut, iFlagLeave);
        if (nRet1 == 0) {
            this.JavaBase64Encode(bImgBuf, iImgLen, bImgBufB64, iImgB64Len);
        }

        return nRet1;
    }

    public int mxGetIsoImage(byte[] bIsoImgBuf, int iIsoImgLen, int iTimeOut, int iFlagLeave) {
        short iDpi = 363;
        short iWidth = 152;
        short iHeight = 200;
        int iImgLen = iIsoImgLen - 54;
        byte[] bImgBuf = new byte[iImgLen];
        int iRV = this.m_hidFingerComm.mxGetImage(bImgBuf, iImgLen, iTimeOut, iFlagLeave);
        if (iRV < 0) {
            return iRV;
        } else {
            ImgFormatTrans.ImgToIso(bImgBuf, iDpi, iWidth, iHeight, bIsoImgBuf);
            return iRV;
        }
    }

    public int mxAutoGetImage(byte[] bImgBuf, int iImgW, int iImgH, int iTimeOut, int iFlagLeave) {
        boolean nRet = false;
        int nRet1 = this.m_hidFingerComm.mxAutoGetImage(bImgBuf, iImgW, iImgH, iTimeOut, iFlagLeave);
        return nRet1;
    }

    public int mxAutoGetIsoImage(byte[] bIsoImgBuf, int iWidth, int iHeight, int iDpi, int iTimeOut, int iFlagLeave) {
        byte[] bImgBuf = new byte[iWidth * iHeight];
        int iRV = this.m_hidFingerComm.mxAutoGetImage(bImgBuf, iWidth, iHeight, iTimeOut, iFlagLeave);
        if (iRV < 0) {
            return iRV;
        } else {
            ImgFormatTrans.ImgToIso(bImgBuf, iDpi, iWidth, iHeight, bIsoImgBuf);
            return iRV;
        }
    }

    public void mxCancelGetImage() {
        this.m_hidFingerComm.mxCancelGetImage();
    }

    public Bitmap Raw2Bimap(byte[] imgBuf, int iImgX, int iImgY) {
        return BMP.Raw2Bimap(imgBuf, iImgX, iImgY);
    }

    public Bitmap Iso2Bimap(byte[] isoImgBuf) {
        return BMP.Iso2Bimap(isoImgBuf);
    }

    public int mxDevUpdate(byte[] bCodbuffer, int codbufferlen) {
        return this.m_hidFingerComm.mxDevUpdate(bCodbuffer, codbufferlen);
    }



    public int zzCloseDev() {
        this.m_hidFingerComm.zzStopFPC();
        return this.m_hidFingerComm.zzCloseDev();
    }

    public int zzAutoUpImage(byte[] bImgBuf, int iImgW, int iImgH, int iTimeOut, int iFlagLeave) {
        boolean nRet = false;
        int nRet1 = this.m_hidFingerComm.zzUpAutoImage(bImgBuf, iImgW, iImgH, Boolean.valueOf(false));
        return nRet1;
    }

    public int JavaBase64Encode(byte[] pInput, int inputLen, byte[] pOutput, int outputbufsize) {
        return mxJavaBase64.JavaBase64Encode(pInput, inputLen, pOutput, outputbufsize);
    }

    public int JavaBase64Decode(byte[] pInput, int inputLen, byte[] pOutput) {
        return mxJavaBase64.JavaBase64Decode(pInput, inputLen, pOutput);
    }

    public void unRegUsbMonitor() {
        this.m_hidFingerComm.unRegUsbMonitor();
    }
}
